package middleware

import (
	"5title_gin/pkg/cache"
	"5title_gin/pkg/utils/http"
	"5title_gin/pkg/utils/jwts"
	"5title_gin/pkg/utils/sys/userUtils"
	"strings"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func AuthMiddleware(c *gin.Context) {
	// 获取并解析 Authorization 头部
	authHeader := c.GetHeader("Authorization")
	parts := strings.Fields(authHeader)
	if len(parts) != 2 || parts[0] != "Bearer" {
		http.FailWithMsg("无效的 Token", c)
		c.Abort()
		return
	}

	token := parts[1]
	zap.S().Infof("Token: %s", token)
	// 验证 Token
	myClaims, err := jwts.CheckToken(token)
	if err != nil {
		if err.Error() == "token is expired" {
			// Token 过期，更新为离线状态
			if myClaims != nil && myClaims.Claims.UserID != 0 {
				if updateErr := userUtils.UpdateUserStatus(myClaims.Claims.UserID, 2); updateErr != nil {
					zap.S().Errorf("更新用户 %d 状态为离线失败: %v", myClaims.Claims.UserID, updateErr)
				}
			}
			http.FailWithMsg("Token 已过期，用户离线", c)
		} else {
			// 其他认证失败（如签名无效），更新为异常状态
			http.FailWithMsg("认证失败", c)
			if myClaims != nil && myClaims.Claims.UserID != 0 {
				if updateErr := userUtils.UpdateUserStatus(myClaims.Claims.UserID, 3); updateErr != nil {
					zap.S().Errorf("更新用户 %d 状态为异常失败: %v", myClaims.Claims.UserID, updateErr)
				}
			}
		}
		c.Abort()
		return
	}

	// 检查 Redis 注销状态
	if cache.HasLogout(token) {
		http.FailWithMsg("当前登录已注销", c)
		// 注销状态应在注销接口中更新，这里不重复操作
		c.Abort()
		return
	}

	// 在Redis中记录用户活动时间
	cache.SetUserLastActive(myClaims.Claims.UserID)

	// 设置上下文
	c.Set("userID", myClaims.Claims.UserID)
	c.Set("roleID", myClaims.Claims.RoleID)
	c.Next()
}

func GetAuth(c *gin.Context) (cl *jwts.MyClaims) {
	cl = new(jwts.MyClaims)
	_claims, ok := c.Get("claims")
	if !ok {
		return
	}
	cl, ok = _claims.(*jwts.MyClaims)
	return
}
